<template>
  <div
    ref="elRef"
    class="table-responsive"
    :style="{ maxHeight: maxHeight }"
    :class="[
      wrapperClass,
      {
        'table-sticky-header': sticky,
      },
    ]"
  >
    <div
      v-bind="$attrs.style"
      :class="[
        $attrs.class,
        { shadow: shadow },
        {
          'border-x border-b border-neutral-200 dark:border-neutral-800':
            bordered,
        },
      ]"
    >
      <table
        :class="[
          'table-primary',
          { 'table-condensed': condensed, 'border-separate': sticky },
        ]"
        v-bind="tableAttrs"
        :style="{ borderSpacing: sticky ? 0 : undefined }"
      >
        <slot></slot>
      </table>
    </div>
  </div>
</template>

<script setup>
import { computed, ref, useAttrs } from 'vue'

defineOptions({
  inheritAttrs: false,
})

defineProps({
  maxHeight: String,
  condensed: Boolean,
  wrapperClass: [String, Object, Array],
  shadow: { default: true, type: Boolean },
  bordered: Boolean,
  sticky: Boolean,
})

const elRef = ref(null)
const attrs = useAttrs()

const tableAttrs = computed(() => {
  const result = { ...attrs }
  delete result.class
  delete result.style

  return result
})

defineExpose({ $el: elRef })
</script>

<style>
.table-responsive {
  @apply touch-auto overflow-x-auto;
}

.table-primary {
  @apply min-w-full divide-y divide-neutral-200 dark:divide-neutral-800;

  > thead,
  > thead > tr > th {
    @apply bg-neutral-50 dark:bg-neutral-700;
  }

  > thead > tr > th {
    @apply border-y border-neutral-200 px-6 py-3 text-xs font-semibold uppercase tracking-wider text-neutral-700 dark:border-neutral-800 dark:text-neutral-100;
  }

  > tbody {
    @apply bg-white dark:bg-neutral-900;

    > tr {
      @apply bg-white dark:bg-neutral-900;

      > td {
        @apply bg-white px-6 py-4 text-sm font-medium text-neutral-800 dark:bg-neutral-900 dark:text-neutral-200;

        &.is-empty {
          @apply text-sm font-normal;
        }
      }

      &:not(:last-child) > td {
        @apply border-b border-neutral-200 dark:border-neutral-800;
      }
    }
  }

  &.table-condensed {
    > thead > tr > th {
      @apply px-2 py-2.5;
    }

    > tbody > tr > td {
      @apply px-2 py-1.5;

      .link {
        @apply text-neutral-700 hover:text-neutral-800 dark:text-neutral-200 dark:hover:text-neutral-300;
      }
    }
  }
}

.table-sticky-header {
  @apply max-h-80 overflow-y-auto;

  table > thead > tr > th {
    @apply sticky top-0 z-10 bg-opacity-75 backdrop-blur-sm backdrop-filter;
  }
}

.table-sticky-header,
.table-responsive {
  table {
    > thead > tr {
      > .table-primary-column {
        @apply z-30 lg:sticky lg:left-0;
      }

      > .table-actions-column {
        @apply z-30 lg:sticky lg:right-0;
      }
    }

    > tbody > tr,
    > tfoot > tr {
      > .table-primary-column {
        @apply relative lg:sticky lg:left-0;
      }

      > .table-actions-column {
        @apply relative bg-neutral-50 px-2 dark:bg-neutral-800 lg:sticky lg:right-0;
      }
    }

    > tbody,
    tfoot {
      > tr {
        > .table-primary-column {
          @apply z-10;
        }

        > .table-actions-column {
          @apply z-20;
        }
      }
    }
  }
}

table > tbody > tr {
  &.row-border-left {
    > td:first-child:after,
    td:first-child:before {
      @apply absolute left-0 top-0 h-full w-auto border-l-2 border-transparent content-[''];
    }
    &.row-border-primary {
      > td:first-child:after,
      td:first-child:before {
        @apply border-primary-500;
      }
    }
    &.row-border-warning {
      > td:first-child:after,
      td:first-child:before {
        @apply border-warning-500;
      }
    }
    &.row-border-danger {
      > td:first-child:after,
      td:first-child:before {
        @apply border-danger-500;
      }
    }
    &.row-border-success {
      > td:first-child:after,
      td:first-child:before {
        @apply border-success-500;
      }
    }
    &.row-border-info {
      > td:first-child:after,
      td:first-child:before {
        @apply border-info-500;
      }
    }
  }
}
</style>
